
#include "./manager.h"

namespace lukv {


time_t manager::sys_time { };

std::vector<sockaddr_in> manager::driver_addrs;

std::vector<sockaddr_in> manager::worker_addrs;

int manager::replication = 1;

std::unordered_map<int, long> manager::expire_cli_socks;

long manager::max_cli_expire_time = 30000000000;

int manager::get_driver_index(const sockaddr_in & sock_addr) {
    for (int i = 0; i < driver_addrs.size(); ++i) {
        if (driver_addrs[i].sin_addr.s_addr == sock_addr.sin_addr.s_addr &&
            driver_addrs[i].sin_port == sock_addr.sin_port &&
            driver_addrs[i].sin_family == sock_addr.sin_family)
        {
            return i;
        }
    }
    return -1;
}

int manager::get_worker_index(const sockaddr_in & sock_addr) {
    for (int i = 0; i < worker_addrs.size(); ++i) {
        if (worker_addrs[i].sin_addr.s_addr == sock_addr.sin_addr.s_addr &&
            worker_addrs[i].sin_port == sock_addr.sin_port &&
            worker_addrs[i].sin_family == sock_addr.sin_family)
        {
            return i;
        }
    }
    return -1;
}

void manager::set_driver_addrs(const std::vector<sockaddr_in> &driverAddrs) {
    driver_addrs = driverAddrs;
}

void manager::set_worker_addrs(const std::vector<sockaddr_in> &workerAddrs) {
    worker_addrs = workerAddrs;
}

void manager::set_max_cli_expire_time(long x) {
    max_cli_expire_time = x;
}

void manager::set_replication(int rep) {
    replication = rep;
}

bool manager::is_node(sockaddr_in & addr) {
    for (const auto & item : driver_addrs) {
        if (addr.sin_port == item.sin_port && addr.sin_family == item.sin_family && addr.sin_addr.s_addr == item.sin_addr.s_addr) {
            return true;
        }
    }
    for (const auto & item : worker_addrs) {
        if (addr.sin_port == item.sin_port && addr.sin_family == item.sin_family && addr.sin_addr.s_addr == item.sin_addr.s_addr) {
            return true;
        }
    }
    return false;
}

void manager::set_expire_cli(int sock) {
    time(&sys_time);
    expire_cli_socks[sock] = (long) sys_time;
}

void manager::remove_expire_cli(int sock) {
    expire_cli_socks.erase(sock);
}

bool manager::cli_expired(int sock) {
    time(&sys_time);
    return (long) sys_time - expire_cli_socks[sock] >= max_cli_expire_time;
}

std::vector<int> manager::get_expired_clis() {
    std::vector<int> ans;
    for (auto & [k, v] : expire_cli_socks) {
        if (cli_expired(k)) {
            ans.emplace_back(k);
        }
    }
    return ans;
}

}
